home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / ansi / hercules.zip / GCHAR.ASM < prev    next >
Assembly Source File  |  1986-09-04  |  14KB  |  530 lines

  1. ;********************************************************************
  2. ;*
  3. ;*    GRAPHIC CHARACTER HANDLING
  4. ;*
  5. ;*        Dave Tutelman - 8/86
  6. ;*
  7. ;*-------------------------------------------------------------------
  8. ;*
  9. ;*    Fn 6    Scroll up - not yet implemented
  10. ;*    Fn 7    Scroll down - not yet implemented
  11. ;*    Fn 9    Write character with attribute
  12. ;*    Fn 10    Write character normal
  13. ;*    Fn 14    Write character Teletypewriter style
  14. ;*
  15. ;*    Also includes subroutines to:
  16. ;*    get_address    convert page/row/col to display address
  17. ;*    do_char        write a character to an address on display
  18. ;*    do_attrib    change a display address to some attribute
  19. ;*    full_screen_scroll    used by Fn 14, when it needs to scroll
  20. ;*    flash        momentarily flash to reverse video and back
  21. ;*
  22. ;********************************************************************
  23. ;
  24. INCLUDE    hercbios.h
  25.  
  26. ;-----------------------------------------------
  27. extrn    exit_herc_bios:near
  28. public    writechar,scroll_up,scroll_down,tty
  29. public    scr_start,scr_length,num_rows
  30. ;------------------------------------
  31. cseg    segment    public
  32.     assume    cs:cseg,ds:bios_data
  33. ;
  34.  
  35. ;**************************************************************
  36. ;*
  37. ;*    FUNCTION 6 & 7 - SCROLL UP & DOWN
  38. ;*    (Placeholder only - not yet implemented)
  39. ;*
  40. ;*    AL = Number of rows to scroll (if 0, blank scroll area)
  41. ;*    BH = Fill attribute (we ignore, since writechar destroys old attrib)
  42. ;*    CX = Upper left corner      (CH=row, CL=col)
  43. ;*    DX = Lower right corner     (DH=row, DL=col)
  44. ;*
  45. ;****************************************************************
  46. ;
  47. scroll_up:
  48. scroll_down:
  49. ;
  50.     jmp    exit_herc_bios
  51. page
  52. ;********************************************************************
  53. ;*
  54. ;*    FUNCTION 9 & 10 - WRITE A CHARACTER AT CURRENT CURSOR
  55. ;*
  56. ;*    AL = character code to be written
  57. ;*    AH = 9 (write char with attribute) or 10 (write char normal)
  58. ;*    BL = new attribute (limited selection in graphics mode)
  59. ;*    BH = display page number
  60. ;*    CX = count of how many characters to write
  61. ;*
  62. ;********************************************************************
  63. ;
  64. writechar:    
  65. ;            ; Get the address corresponding to cursor[page]
  66.     push    bx
  67.     mov    bl,bh        ; page to BX
  68.     xor    bh,bh
  69.     shl    bx,1        ; *2 for word pointer
  70.     mov    dx,curs_pos[bx]    ; appropriate cursor position to DX
  71.     pop    bx
  72.     call    get_address    ; get display address in DI
  73. ;
  74. wrchar_loop:
  75. ;            ; Write a character to that address
  76.     call    do_char        ; arguments set up already
  77. ;
  78. ;            ; If function 9, modify the character's attributes
  79.     cmp    ah,9        ; Function 9?
  80.     jne    no_attrib    ; no, don't do attributes
  81.     call    do_attrib    ; yes, and arguments already set up
  82. no_attrib:
  83. ;
  84.     inc    di        ; move to next position, without moving
  85.                 ;    the official cursor
  86.     loop    wrchar_loop    ; continue until CX count exhausted
  87.     jmp    exit_herc_bios
  88. page
  89. ;*****************************************************************
  90. ;*
  91. ;*    FUNCTION 14 - TELETYPEWRITER-STYLE CHARACTER WRITE
  92. ;*
  93. ;*    AL = Character to be written
  94. ;*
  95. ;******************************************************************
  96. ;
  97. tty:
  98.     assume    ds:bios_data
  99.     mov    bl,active_page    ; active page to BX
  100.     xor    bh,bh
  101.     mov    dx,curs_pos[bx]    ; get cursor for active page
  102.     push    bx
  103.     mov    bh,bl        ; move page to BH
  104.     call    get_address    ; address of character to DI
  105.     pop    bx
  106. ;
  107. ;            ; process the character
  108. ;            ; check if CR
  109.     cmp    al,13        ; carriage return?
  110.     jne    not_cr
  111.     mov    dl,0        ; go to first column
  112.     jmp    fix_curs
  113. ;            ; check if LF
  114. not_cr:    cmp    al,10        ; line feed?
  115.     jne    not_lf
  116.     inc    dh        ; next line
  117.     jmp    fix_curs
  118. ;            ; check if BS
  119. not_lf:    cmp    al,8        ; backspace?
  120.     jne    not_bs
  121.     cmp    dl,0        ; already first column?
  122.     je    fix_curs    ; yup. do nothing
  123.     dec    dl        ; nope. move cursor left one
  124.     dec    di        ; also move address pointer left one
  125.     mov    al,32        ; set character to space
  126.     call    do_char        ; and write the space, but don't move
  127.     jmp    fix_curs
  128. ;            ; check if BEL
  129. not_bs:    cmp    al,7        ; bell character?
  130.     jne    not_bl
  131.     pop    es        ; restore registers
  132.     pop    di
  133.     pop    si
  134.     pop    dx
  135.     pop    cx
  136.     pop    bx
  137.     pop    ds
  138.     jmp    vid_bios    ; ... and use the normal BIOS to ring the bell
  139. ;    call    flash        ; can't do BEL standard. Blink display instead
  140. ;    jmp    fix_curs
  141. ;            ; ordinary printing character, so display it
  142. not_bl:    call    do_char        ; write it to screen
  143.     inc    dl        ; cursor one to the right
  144. ;
  145. ;            ; now look at the cursor, do what's necessary to
  146. ;            ; fix it up, and save it away.
  147. fix_curs:
  148.     cmp    dl,89        ; beyond last column?
  149.     jle    chk_scroll    ; not yet
  150.     xor    dl,dl        ; yes. do a CR
  151.     inc    dh        ; ... and a LF
  152. chk_scroll:
  153.     cmp    dh,cs:num_rows    ; now see if we're beyond last row?
  154.     jl    exit_tty    ; not yet
  155.     call    full_screen_scroll
  156.                 ; yes. Scroll the screen up one
  157.     dec    dh        ; ... and scroll cursor, too.
  158.     jmp    chk_scroll
  159. ;
  160. exit_tty:
  161.     mov    curs_pos[bx],dx    ; save cursor position
  162.     jmp    exit_herc_bios
  163. page
  164. ;--------------------------------------------------------------------
  165. ;
  166. ;    GET_ADDRESS  SUBROUTINE
  167. ;
  168. ;    BH = display page
  169. ;    DX = cursor position (DH=row, DL=col)
  170. ;
  171. ;    returns:
  172. ;    DI = displacement of top row of pixels
  173. ;
  174. ;--------------------------------------------------------------------
  175. ;
  176. get_address:
  177.     push    cx        ; save it
  178.  
  179. ;            ; compute display address from cursor_pos
  180.     mov    cl,dh        ; get row # in cx
  181.     xor    ch,ch
  182.     shl    cx,1        ; begin fast multiply by 90 (1011010 B)
  183.     mov    di,cx
  184.     shl    cx,1
  185.     shl    cx,1
  186.     add    di,cx
  187.     shl    cx,1
  188.     add    di,cx
  189.     shl    cx,1
  190.     shl    cx,1
  191.     add    di,cx        ; end fast multiply by 90
  192.     mov    cx,di        ; copy answer back to cx
  193.     shl    di,1        ; *2 for ibm graphics mode
  194.     cmp    video_mode,herc_mode
  195.     jne    ibm_ad        ; not herc mode
  196.     add    di,cx        ; *3 for herc mode
  197. ibm_ad:    xor    ch,ch        ; columns in CX
  198.     mov    cl,dl
  199.     add    di,cx        ; add in col. address in DI
  200.     cmp    bh,0        ; if page 1, set high-order bit of address
  201.     je    pg0
  202.     or    di,8000H
  203. pg0:
  204. ;            ; address now in DI
  205. ;
  206.     pop    cx        ; restore it
  207.     ret
  208. page
  209. ;--------------------------------------------------------------------
  210. ;
  211. ;    DO_CHAR  SUBROUTINE
  212. ;
  213. ;    AL = character to write
  214. ;    DI = diplacement (address) of top row of pixels
  215. ;
  216. ;    Note: SI and ES are destroyed
  217. ;
  218. ;--------------------------------------------------------------------
  219. ;
  220. do_char:
  221.     push    ax
  222.     push    bx
  223.     push    cx
  224.     push    di
  225.     push    ds
  226. ;
  227. ;            ; get scan pattern table pointer into BX
  228.     cmp    video_mode,herc_mode
  229.     je    herc_1
  230.     mov    bx,offset ibm_pattern
  231.                 ; IBM graphics mode - use appropriate table
  232.     jmp    c_1
  233. herc_1:    mov    bx,offset herc_pattern
  234.                 ; herc graphics mode - use appropriate table
  235. c_1:
  236. ;
  237. ;            ; set up source address registers
  238.     xor    ah,ah        ; character to SI
  239.     mov    si,ax
  240. IFDEF iAPX286
  241.     shl    si,3        ; *8 for 8-byte table entry
  242. ELSE
  243.     shl    si,1        ; *8 for 8-byte table entry
  244.     shl    si,1
  245.     shl    si,1
  246. ENDIF
  247.                 ; next, find beginning of table
  248.     cmp    al,7Fh        ; ROM or user table?
  249.     jg    u_tbl
  250.                 ; ROM table
  251.     add    si,charbase    ; character table base added to offset
  252.     mov    ax,mpx_bios    ; BIOS code segment to DS
  253.     mov    ds,ax
  254.     jmp    c_2
  255. u_tbl:                ; user table
  256.     xor    ax,ax        ; zero (interrupt vector) to DS
  257.     mov    ds,ax
  258.     mov    ax,si        ; save table offset in AX
  259.     assume    ds:intvec
  260.     lds    si,user_table    ; load DS:SI from interrupt vector
  261.     add    si,ax        ; add offset into table base
  262. c_2:
  263. ;
  264. ;            ; set up destination address registers
  265.     mov    ax,pixbase    ; get display segment in ES
  266.     mov    es,ax
  267.                 ; displacement already in DI
  268. ;
  269. ;
  270. ;            ; transfer the character
  271.     mov    ax,di        ; save top-row displacement in AX
  272.     mov    cx,8        ; transfer 8 rows
  273.     cld            ; direction = up
  274. c_loop:    mov    di,ax        ; top-row displacement
  275.     add    di,cs:[bx]    ; add entry from scan-pattern table
  276.     movsb            ; actually transfer a byte and bump SI & DI
  277.     add    bx,2        ; next entry in scan-pattern table
  278.     loop    c_loop
  279. ;
  280. ;            ; if hercules mode, blank the extra rows
  281.     pop    ds        ; restore DS to Bios data
  282.     assume    ds:bios_data
  283.     cmp    video_mode,herc_mode
  284.     jne    c_3
  285.                 ; Hercules mode
  286.     mov    si,ax        ; don't need SI. Save top-row displacement
  287.     xor    ax,ax        ; zero AX
  288.     mov    cx,4        ; four rows to blank
  289.     cld
  290. c_blnk: mov    di,si        ; top-row displacement
  291.     add    di,cs:[bx]    ; add entry from scan-pattern table
  292.     stosb            ; transfer a zero byte
  293.     add    bx,2        ; next entry in scan-pattern table
  294.     loop    c_blnk
  295. c_3:
  296. ;
  297. ;            ; clean up and return
  298.     pop    di
  299.     pop    cx
  300.     pop    bx
  301.     pop    ax
  302.     ret
  303. page
  304. ;------------------------------------------------------------------